# coding=utf-8

import sys
import jieba
import jieba.posseg
import python_library.mysql.connector as connector
import python_library.utils as utils
from ConfigParser import ConfigParser
reload(sys)
sys.setdefaultencoding("utf-8")


class BindConfig(object):
  """绑定配置文件信息
  """

  # 数据库连接
  DB = {}

  # 相似度判定阈值上限，大于等于该值将绑定
  THRESHOLD = 9999

  # 相似度判定阈值下限，小于等于该值将生成
  FLOOR_THRESHOLD = 0

  # 名称字段组合，以,拼接
  NAME_FIELDS = ""

  # 为补齐新算法所需字段添加的sql查询字段
  NAME_SQL_FOR_NEW_ALG = ",name AS original_name,name_ot,name_fr"

  # 为补齐新算法所需字段添加的key
  NAME_FOR_NEW_ALG = ",original_name,name_ot,name_fr"

  # 新算法得分判定区间
  NEW_SCORE = [-0.1, 0.1, 0.6, 0.7]

  # album表待查询字段名，以,拼接
  ALBUM_FIELDS = ""

  # video表待查询字段名，以,拼接
  VIDEO_FIELDS = ""

  # video表与album表同义不同名字段映射关系
  # 例如
  # intro:description,video_name:album_name --> {'intro': 'description', 'video_name': 'album_name'}
  # 其中:前面的值来自于video表，后面的值来自于album表
  VIDEO_ALBUM_MAP = {}

  # 编码
  ENCODING = "UTF-8"

  # 打印debug log时各主要模块间的醒目提示符
  LOG_MARK = "================================================"

  @staticmethod
  def init_bind_config():
    """初始化绑定配置信息
    """

    def strip_all(str):
      """移除传入字符串中所有的空白字符
         例如：
         "dd             d d" --> dddd
         "灵 梦             d  d" --> 灵梦dd

      Args:
        str: 传入字符串

      Returns:
        移除空白字符后的字符串
      """
      return utils.erase_all(str, " \r\n\t")

    config_parser = ConfigParser()
    config_parser.read("config/auto_binding.conf")
    BindConfig.DB = dict(config_parser.items("db"))
    BindConfig.THRESHOLD = config_parser.getint("base", "threshold")
    BindConfig.FLOOR_THRESHOLD = config_parser.getint("base", "floor_threshold")
    BindConfig.NAME_FIELDS = strip_all(config_parser.get("base", "name_fields"))
    BindConfig.ALBUM_FIELDS = strip_all(config_parser.get("base", "album_fields"))
    BindConfig.VIDEO_FIELDS = strip_all(config_parser.get("base", "video_fields"))
    BindConfig.VIDEO_ALBUM_MAP = utils.FromStrToDict(config_parser.get("base", "video_album"), False, False, (",", ":"))


class MySQLConn(object):
  """数据库连接
  """

  def __init__(self, db_conf):
    self._db_conf = db_conf

  def __enter__(self):
    self._conn = connector.connect(**self._db_conf)
    return self

  def __exit__(self, exc_type, exc_val, exc_tb):
    self._conn.close()
    return False

  def get(self):
    return self._conn


class ErrCode:
  """记录变量：http接口返回标志及含义
  """

  EXCEPT = (-1, "exception error")
  OK = (0, "ok")
  INVALID_VIDEOID = (1, "invalid video id")
  INVALID_ALBUMID = (2, "invalid album id")
  WRONG_PARAM = (3, "wrong parameters")
  MATCHED = (5, "matched")
  NEW_ALBUM = (6, "new_album")
  LACK_FIELDS = (7, "lack fields")
  NOTHING = (8, "do nothing")
  FILTERED = (9, "filtered")
  NO_COMPARISON = (10, "no comparison")


class BindCommon(object):
  """各绑定相关类所需静态方法
  """

  @staticmethod
  def denoise_string(string, noise_words=None):
    """移除干扰字符，并将所有英文字母变为大写
       例如：
       denoise_string("摸,dd。d摸'“”·・:(a摸大", noise_words=[",", "摸"])
       --> DD。DA大

    Args:
      string: 待操作字符串
      noise_words: 可选字段，默认为None。若该值为空则移除默认干扰字符。
                   可传入一个列表，列表中的字符将在本次操作中添加至默认干扰字符中

    Returns:
      移除结果
    """
    if not string or not isinstance(string, basestring) or not string.strip():
      return None
    noise_list = list(u"""\n\t\r" '`‘’“”·・:()（）《》：""")
    if noise_words:
      noise_list.extend(noise_words)
    return reduce(lambda x, y: x.replace(y, ""), noise_list, string.upper().strip())

  @staticmethod
  def massage(data):
    """操作传入字典中的特定字段值

    Args:
      data: 字典信息

    Returns:
      操作后的结果
    """
    data["original_description"] = data["description"]
    data["original_actor_name"] = data["actor_name"]
    data["original_director_name"] = data["director_name"]
    data["original_category_name"] = data["category_name"]
    data["description"] = BindCommon.denoise_string(data["description"], [u"简介"])
    for k in ["name", "actor_name", "director_name", "category_name"]:
      v = data[k]
      if not v:
        continue
      if k == "category_name":
        v = utils.erase_all(v, u"片剧")
      data[k] = [clip for clip in BindCommon.denoise_string(v).replace(",", ";").split(";") if clip]
    return data

  @staticmethod
  def sentence_segment(sentence):
    """分词

    Args:
      sentence: 待分词字符串

    Returns:
      分词结果列表
    """
    return [seg.word for seg in jieba.posseg.cut(sentence)
            if all(seg.flag.find(flag) == -1 for flag in "eouwxy")]

  @staticmethod
  def translate_for_new(data, video_type):
    """将传入数据转换为新算法可用的结构

    Args:
      data: 字典信息
      video_type: 类型--电影，电视剧...

    Returns:
      操作后的结果
    """
    if not data:
      return {}
    result = {}
    result["video_type"] = video_type
    result["name_ot"] = data.get("name_ot")
    result["name_fr"] = data.get("name_fr")
    result["episodes"] = data.get("episodes")
    result["screen_time"] = data.get("screen_time")
    result["screen_year"] = data.get("screen_year")
    result["description"] = data.get("original_description")
    result["language_name"] = data.get("language_name")
    result["area_name"] = data.get("area_name")
    result["actor_name"] = data.get("original_actor_name")
    result["director_name"] = data.get("original_director_name")
    result["category_name"] = data.get("original_category_name")
    result["name"] = data.get("original_name")
    return result